home *** CD-ROM | disk | FTP | other *** search
- ; Joystick control module
- ; <bashing mode on>
- ; Grrr! Why those wimpy IBM engineers chosed a stupid analog interface ?!?!?
- ; Heck! If at least they included enough hardware support this
- ; could have been a little problem, but ...argh!...
- ; I hate polling things when lots of IRQs keeps knocking on the P.I.C. !!!!
- ; Of course this is the "default stick" handling code, if you plan to
- ; add cooler sticks, just write a XID driver and let it take control.
- ; <bashing mode off>
- ;
- ; Well, this is my "safe" joystick handling code
- ; there are better ways to handle sticks, but i know this works on anything
-
- ; _InitStick
- ; _ReadStick
-
- .386P
-
- code32 segment para public use32
- assume cs:code32,ds:code32
- include 386power.inc
- include 386video.inc
- include pix.inc
- include chario.inc
- include 386keyb.inc
- include 386menu.inc
-
- ; What is needed to read the joystick port:
- ;1. Trigger the joystick oneshots with an 'out' to 0x201.
- ; This will set all of the joystick bits on.
-
- ;2. Read (in) 0x201, finding:
-
- ; Bit Contents
- ; 0 Joystick A X coordinate
- ; 1 Joystick A Y coordinate
- ; 2 Joystick B X coordinate
- ; 3 Joystick B Y coordinate
- ; 4 Button A 1
- ; 5 Button A 2
- ; 6 Button B 1
- ; 7 Button B 2
- ;
- ;3. Continue reading 0x201 until ALL oneshots return to zero
- ; (i've seen lots of joystic routines that seems to miss this)
- ; recording the loop during which each bit falls to zero.
- ; The duration of the pulse from each oneshot may be used to
- ; determine the resistive load (from 0 to 100K) from each
- ; Joystick, as: Time = 24.2msec. + .011 (r) msec.
- ;
- ;4. To do this correctly, I recommend calibrating the joystick;
- ; have the user move the stick to each corner, then center it,
- ; while recording the resulting values.
-
- align dword
- ; the following DWORDS the "downcount value" reached when
- ; the corresponding bit in the joystick port
- ; has gone under the "logic 1" threshold value.
- _JX_A dd 0
- _JY_A dd 0
- _JX_B dd 0
- _JY_B dd 0
- _B1_A dd 0
- _B2_A dd 0
- _B1_B dd 0
- _B2_B dd 0
-
- ; calibration parameters for joystick A
- A_YUP dd 0
- A_XLEFT dd 0
- A_YCENTER dd 0
- A_XCENTER dd 0
- A_YDOWN dd 0
- A_XRIGHT dd 0
-
-
- ; calibration parameters for joystick B
- B_YUP dd 0
- B_XLEFT dd 0
- B_YCENTER dd 0
- B_XCENTER dd 0
- B_YDOWN dd 0
- B_XRIGHT dd 0
-
- _BUTTON dd 0
-
- _POLL_TIME dd 00000FFFFh ; usually this is fast enough
- ; MAX. NUMBER OF LOOPS WE HAVE TO PERFORM
- ; TO COMPLETELY DECODE THE JOYSTICK PORT
- ; (during calibration it will be set to the higher
- ; "poll" value to speed up joystick reads)
-
- JPORT equ 0201h
-
- ; MAX. 30 chars for every name
- IBMStick db 'plain joystick',0
-
- ; joysticks name table
- public _StickName
- _StickName dd offset IBMStick
- dd 0,0,0
-
- ; check joystick
- SOK dd offset OkMIStick,offset snone,offset snone,offset snone
-
- ; init stick table
- IStick dd offset MIStick, offset snone, offset snone, offset snone
-
- align byte
- public _StickOK
- _StickOK:
- jmp [esi*4+SOK]
-
- OkMIStick:
- stc
- ret
-
- public _InitStick
- _InitStick:
- jmp [esi*4+IStick]
-
- nojoys db 'XID: Invalid joystick device',CR,LF,'$'
- snone: mov _386Return,offset nojoys
- jmp _Exit
-
- head db ' pc joystick calibration ',0
- tail db ' and press a button ',0
-
- center db 'MOVE TO CENTRAL POSITION',0
- upleft db 'MOVE TO UPPER LEFT POSITION',0
- dnright db 'MOVE TO LOWER RIGHT POSITION',0
- xug db ' x_1=',0
- db ' y_1=',0
- db ' x_2=',0
- db ' y_2=',0
- db 'b0_1=',0
- db 'b1_1=',0
- db 'b0_2=',0
- db 'b1_2=',0
-
-
- ctr1 dd 0
- ctr2 dd 0
- Shuu:
- pushad
- mov edi,_ScrBase
- mov eax,_VDispX
- mov esi,offset _JX_A
- mov ctr1,2
- add eax,6*8
- luup1:
- mov edx,_VDispY
- add edx,100
- mov ctr2,4
- luup2:
- mov ebx,[esi]
- add esi,4
- mov ecx,8
- call _PutUnsigned
- mov ecx,16
- mov ebx,8
- sub eax,_VDispX
- sub edx,_VDispY
- call _TouchBlock
- add eax,_VDispX
- add edx,_VDispY
- add edx,16
- dec ctr2
- jnz luup2
- add eax,8*(6+8+2+6)
- dec ctr1
- jnz luup1
- call _PageFlip1
- popad
- ret
-
- Shoo:
- ; esi = new message
- pushad
- mov eax,0
- call _ScrClr
- mov eax,_VDispX
- mov edx,_VDispY
- add eax,64
- add edx,16
- mov edi,_ScrBase
- mov ebx,offset head
- call _PutString
- add edx,16
- mov ebx,esi
- call _PutString
- add edx,16
- mov ebx,offset tail
- call _PutString
- ; now write the x/y button markers
- mov edi,_ScrBase
- mov eax,_VDispX
- mov ctr1,2
- mov ebx,offset xug
- bluup1:
- mov edx,_VDispY
- add edx,100
- mov ctr2,4
- bluup2:
- call _PutString
- add ebx,6
- add edx,16
- dec ctr2
- jnz bluup2
- add eax,(6+8+2)*8
- dec ctr1
- jnz bluup1
-
- call _PageFlip0
- popad
- ret
-
- CP macro a,b
- mov eax,b
- mov a,eax
- endm
-
- ReleaseButton: ;wait until the pressed button is released
- call RawStick
- mov eax,_BUTTON
- cmp _B1_A,eax
- jbe ReleaseButton
- cmp _B2_A,eax
- jbe ReleaseButton
- cmp _B1_B,eax
- jbe ReleaseButton
- cmp _B2_B,eax
- jbe ReleaseButton
- ret
-
-
- MIStick: ; main joystick initialization
- pushad
-
- ; check lower right corner first
- ; to get maximum poll times
- mov esi,offset dnright
- call Shoo
- rednright:
- call RawStick
- call Shuu
- CP A_XRIGHT,_JX_A
- mov ebx,eax
- CP A_YDOWN,_JY_A
- cmp ebx,eax
- ja alto1
- mov ebx,eax
- alto1:
- CP B_XRIGHT,_JX_B
- cmp ebx,eax
- ja alto2
- mov ebx,eax
- alto2:
- CP B_YDOWN,_JY_B
- cmp ebx,eax
- ja alto3
- mov ebx,eax
- alto3: lea eax,[ebx*2]
- cmp _B1_A,eax
- jbe doned
- cmp _B2_A,eax
- jbe doned
- cmp _B1_B,eax
- jbe doned
- cmp _B2_B,eax
- jnbe rednright
- doned: add ebx,4
- mov _POLL_TIME,ebx ; set maximum polling time to speed up things
-
- ; check upper left corner to get a better button threshold
- mov esi,offset upleft
- call Shoo
- call ReleaseButton
- reupleft:
- call RawStick
- call Shuu
- CP A_XLEFT,_JX_A
- mov ebx,eax
- CP A_YUP,_JY_A
- cmp ebx,eax
- jb basso1
- mov ebx,eax
- basso1:
- CP B_XLEFT,_JX_B
- cmp ebx,eax
- jb basso2
- mov ebx,eax
- basso2:
- CP B_YUP,_JY_B
- cmp ebx,eax
- jb basso3
- mov ebx,eax
- basso3: shl ebx,1 ; keep a good margin
- add ebx,4 ; & set new minimum button threshold
- mov _BUTTON,ebx
- cmp _B1_A,ebx
- jbe doneu
- cmp _B2_A,ebx
- jbe doneu
- cmp _B1_B,ebx
- jbe doneu
- cmp _B2_B,ebx
- jnbe reupleft
- doneu:
- ; check central positions to centrate the x-y thresholds
- mov esi,offset center
- call Shoo
- call ReleaseButton
- recenter:
- call RawStick
- call Shuu
- CP A_XCENTER,_JX_A
- CP A_YCENTER,_JY_A
- CP B_XCENTER,_JX_B
- CP B_YCENTER,_JY_B
- mov ebx,_BUTTON
- cmp _B1_A,ebx
- jbe donec
- cmp _B2_A,ebx
- jbe donec
- cmp _B1_B,ebx
- jbe donec
- cmp _B2_B,ebx
- jnbe recenter
- donec:
-
-
- ; NOW CALIBRATE THINGS
- mov eax,A_XCENTER
- add eax,A_XLEFT
- shr eax,1
- mov A_XLEFT,eax
- mov eax,B_XCENTER
- add eax,B_XLEFT
- shr eax,1
- mov B_XLEFT,eax
-
- mov eax,A_YCENTER
- add eax,A_YUP
- shr eax,1
- mov A_YUP,eax
- mov eax,B_YCENTER
- add eax,B_YUP
- shr eax,1
- mov B_YUP,eax
- ; now set the "down right" limits
- mov eax,A_XRIGHT
- add eax,A_XCENTER
- shr eax,1
- mov A_XRIGHT,eax
- mov eax,B_XRIGHT
- add eax,B_XCENTER
- shr eax,1
- mov B_XRIGHT,eax
- mov eax,A_YDOWN
- add eax,A_YCENTER
- shr eax,1
- mov A_YDOWN,eax
- mov eax,B_YDOWN
- add eax,B_YCENTER
- shr eax,1
- mov B_YDOWN,eax
- mov eax,0
- call _ScrClr
- call _PageFlip0
- popad
- ret
-
-
-
-
- RawStick:
- mov ecx,_POLL_TIME
- mov dx,JPORT
- ; azzera
- xor ebx,ebx
- mov _JX_A,ebx
- mov _JY_A,ebx
- mov _JX_B,ebx
- mov _JY_B,ebx
- mov _B1_A,ebx
- mov _B2_A,ebx
- mov _B1_B,ebx
- mov _B2_B,ebx
- mov al,0FFh ; call me paranoid :)
- cli
- out dx,al ; trigger RCs
-
- girastick:
- in al,dx ; leggi lo stato delle linee del joystick
- ; aggiorna i contatori
- shr al,1
- adc _JX_A,ebx
- shr al,1
- adc _JY_A,ebx
- shr al,1
- adc _JX_B,ebx
- shr al,1
- adc _JY_B,ebx
- shr al,1
- adc _B1_A,ebx
- shr al,1
- adc _B2_A,ebx
- shr al,1
- adc _B1_B,ebx
- shr al,1
- adc _B2_B,ebx
- dec ecx
- jne girastick
- stickdone:
- sti
- ret
-
- ; read stick table
- RStick dd offset MRStick,offset snone,offset snone,offset snone
-
- public _ReadStick
- _ReadStick:
- jmp [esi*4+RStick]
-
- ; IN: ESI = STICK DEVICE GROUP
- ; OUT: EAX = STICK BITS for joystick 0,1
- ; EDX = STICK BITS for joystick 2,3
- ;
- ; AX = STICK0
- ; EAX high word = STICK1
- ; DX = STICK2
- ; EDX high word = STICK3
- ; Every joystick is described by 16 bits
- ; (it includes 3D motion and 3D rotation plus four buttons)
- ; bit meaning
- ; 0 UP
- ; 1 DOWN
- ; 2 LEFT
- ; 3 RIGHT
- ; 4 FORWARD
- ; 5 BACKWARD
- ; 6 TURN_UP = rotate forward-->up
- ; 7 TURN_DOWN = rotate forward-->down
- ; 8 TURN_LEFT = rotate forward-->left
- ; 9 TURN_RIGHT = rotate forward-->right
- ; 10 ROLL_LEFT = rotate up-->left
- ; 11 ROLL_RIGHT = rotate up-->right
- ; 12 BUTTON_0
- ; 13 BUTTON_1
- ; 14 BUTTON_2
- ; 15 BUTTON_3
-
- J_UP =1
- J_DOWN =2
- J_LEFT =4
- J_RIGHT =8
- J_FORWARD =16
- J_BACKWARD =32
- J_TUP =64
- J_TDOWN =128
- J_TLEFT =256
- J_TRIGHT =512
- J_RLEFT =1024
- J_RRIGHT =2048
- J_B0 =4096
- J_B1 =8192
- J_B2 =16384
- J_B3 =32768
- UPPER_STICK =65536
-
- MRStick : ; read main joysticks
- push ebx
- push ecx
- call RawStick
- ; x axis translation raw->logical
- mov ebx,_JX_A
- mov eax,J_UP+J_LEFT+((J_LEFT+J_UP)*UPPER_STICK)
- cmp ebx,A_XLEFT
- jb done_xa
- xor al,J_LEFT
- cmp ebx,A_XRIGHT
- jb done_xa
- or al,J_RIGHT
- done_xa:
- ; y axis translation raw->logical
- mov ebx,_JY_A
- cmp ebx,A_YUP
- jb done_ya
- xor al,J_UP
- cmp ebx,A_YDOWN
- jb done_ya
- or al,J_DOWN
- done_ya:
- ; traduzione pulsanti 1= pressed 0 = not pressed
- mov edx,_BUTTON
- cmp _B1_A,edx
- ja nob1a
- or ax,J_B0
- nob1a:
- cmp _B2_A,edx
- ja nob2a
- or ax,J_B1
- nob2a: ; NOW TEST SECOND JOYSTICK
- mov ebx,_JX_B
- cmp ebx,B_XLEFT
- jb done_xb
- xor eax,UPPER_STICK*J_LEFT
- cmp ebx,B_XRIGHT
- jb done_xb
- or eax,UPPER_STICK*J_RIGHT
- done_xb:
- ; y axis translation raw->logical
- mov ebx,_JY_B
- cmp ebx,B_YUP
- jb done_yb
- xor eax,UPPER_STICK*J_UP
- cmp ebx,B_YDOWN
- jb done_yb
- or eax,UPPER_STICK*J_DOWN
- done_yb:
- ; traduzione pulsanti 1= pressed 0 = not pressed
- mov edx,_BUTTON
- cmp _B1_B,edx
- ja nob1b
- or eax,UPPER_STICK*J_B0
- nob1b:
- cmp _B2_B,edx
- ja nob2b
- or eax,UPPER_STICK*J_B1
- nob2b:
-
- ; sticks 0,1 present
- pop ecx
- xor edx,edx ; sticks 2,3 are not present
- pop ebx
- ret
-
- code32 ends
- END
-